﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Milkify.Interfaces;
using Milkify.Data;
using System.ComponentModel;
using Milkify.Input;

namespace Milkify.Views
{
    /// <summary>
    /// Interaction logic for PickerPopupControl.xaml
    /// </summary>
    public partial class PickerPopupControl : Window, IPickerView
    {
        private static TypeConverter sKeyConverter = TypeDescriptor.GetConverter(typeof(Key));

        private string mLabelFilter = string.Empty;
        public string LabelFilter
        {
            get { return mLabelFilter; }
            set
            {
                mLabelFilter = value;
                OnTagFilterChanged();
            }
        }

        public PickerPopupControl()
        {
            InitializeComponent();

            ListLabels.Loaded += new RoutedEventHandler(ListLabels_Loaded);
            ListLabels.PreviewKeyDown += new KeyEventHandler(ListLabels_KeyDown);
            ListLabels.PreviewKeyUp += new KeyEventHandler(ListLabels_KeyUp);
            ListLabels.PreviewTextInput += new TextCompositionEventHandler(ListLabels_TextInput);
            ListLabels.MouseDoubleClick += new MouseButtonEventHandler(ListLabels_MouseDoubleClick);
        }

        private void ListLabels_Loaded(object sender, RoutedEventArgs e)
        {
            ListLabels.ItemContainerGenerator.StatusChanged += new EventHandler(ItemContainerGenerator_StatusChanged);
            ItemContainerGenerator_StatusChanged(ListLabels.ItemContainerGenerator, EventArgs.Empty);
        }

        private void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
        {
            if (ListLabels.ItemContainerGenerator.Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
            {
                if (FocusHelper.FocusFirstItem(ListLabels))
                    ListLabels.ItemContainerGenerator.StatusChanged -= new EventHandler(ItemContainerGenerator_StatusChanged);
            }
        }

        private void ListLabels_TextInput(object sender, TextCompositionEventArgs e)
        {
            if (e.Text == "\t" || e.Text == "\b" || e.Text == "\r" || e.Text == "\n")
                return;

            e.Handled = true;
            LabelFilter += e.Text;
        }

        private void ListLabels_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Escape)
            {
                e.Handled = true;
                if (string.IsNullOrEmpty(LabelFilter))
                {
                    DialogResult = false;
                    Close();
                }
                else
                {
                    LabelFilter = null;
                }
            }
            else if (e.Key == Key.Back || e.Key == Key.Delete)
            {
                e.Handled = true;
                if (LabelFilter.Length > 0)
                    LabelFilter = LabelFilter.Substring(0, LabelFilter.Length - 1);
            }
            else if (e.Key == Key.Enter || e.Key == Key.Return)
            {
                e.Handled = true;

                ICollectionView labelsView = GetLabelsCollectionView();
                if (labelsView.CurrentItem != null ||
                    labelsView.MoveCurrentToFirst())
                {
                    DialogResult = true;
                }

                Close();
            }
        }

        private void ListLabels_KeyUp(object sender, KeyEventArgs e)
        {
        }

        private void ListLabels_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            ICollectionView labelsView = GetLabelsCollectionView();
            if (labelsView.CurrentItem != null)
            {
                DialogResult = true;
                Close();
            }
        }

        private ICollectionView GetLabelsCollectionView()
        {
            if (ViewData == null)
                throw new InvalidOperationException("No view data has been set.");

            var viewData = (PickerViewData)ViewData;
            ICollectionView labelsView = CollectionViewSource.GetDefaultView(viewData.Labels);
            return labelsView;
        }

        private void OnTagFilterChanged()
        {
            ICollectionView labelsView = GetLabelsCollectionView();

            if (string.IsNullOrEmpty(mLabelFilter))
            {
                TextFilter.Text = Resources["DefaultTextFilterMessage"] as string;
                labelsView.Filter = null;
            }
            else
            {
                TextFilter.Text = mLabelFilter;
                labelsView.Filter = t => ((string)t).StartsWith(mLabelFilter, StringComparison.CurrentCultureIgnoreCase);
            }

            labelsView.MoveCurrentToFirst();
        }

        #region IPickerView Members

        public string SelectedLabel
        {
            get
            {
                if (ViewData == null)
                    return null;

                var viewData = (PickerViewData)ViewData;
                ICollectionView labelsView = CollectionViewSource.GetDefaultView(viewData.Labels);
                return labelsView.CurrentItem as string;
            }
        }

        #endregion

        #region IView Members

        public object ViewData
        {
            get { return DataContext; }
            set
            {
                if (!(value is PickerViewData))
                    throw new InvalidOperationException("The view data must be of type PickerViewData.");
                DataContext = value;
                LabelFilter = null;
            }
        }

        #endregion
    }
}
